package cn.csq.design.creatation.prototype;

import java.util.HashMap;
import java.util.Map;

/**
 * @author csq
 * @version 1.0.0
 * @ClassName SelfMybatisImpl2.java
 * @Description
 *  场景设计： SelfMybatisImpl2 操作数据库，从数据库里面查找出很多记录，70%改变很少
 *           2、每次查询数据库，查到以后把所有数据都封装一个对象返回
 *              1000Thread 查询一个记录 new User("zhangsan",18)
 *              每次创建一个对象封装并返回 系统里面就用有10000个User 浪费内存
 *           3、解决：缓存：查询过的保存 如果再查相同的记录，拿到的原来的原型对象
 * @createTime 2022年01月03日 16:42:00
 */
public class SelfMybatisImpl3 implements SelfMybatis {

    //缓存User
    private Map<String, User> userCache = new HashMap<>();

    /**
     * 从数据库查询数据
     * 如果不使用缓存，每次都是从数据库查询，每次都会创建User对象
     *
     * @param username
     * @return
     */
    @Override
    public User getUser(String username) throws CloneNotSupportedException {
        //第二版 添加缓存节省效率 只创建一次User
        //如果缓存中没有
        User user = null;
        if (!userCache.containsKey(username)) {
            //从数据库查询
            user = getUserFromDB(username);
            //重点注意的地方 第一次没有从数据库中获取
        } else {
            //从缓存中获取  从缓存中直接获取就会变脏  脏缓存问题  本人
            user = userCache.get(username);
            //第三版 原型已经拿到，但是不能直接给
            //从这个对象中快速得到一个克隆体 不能修改本人 ，获取到克隆人==原型模式
            System.out.println("从缓存中获取到的" + user);
            //返回它的克隆对象
            user = user.clone();
        }
        return user;
    }

    //第二版 添加缓存
    private User getUserFromDB(String username) throws CloneNotSupportedException {
        System.out.println("从数据库查到"+username);
        //从数据获取
        User user = new User();
        user.setName(username);
        user.setAge(18);
        //添加缓存
        //第三版，添加缓存的时候添加它的克隆体
        User clone = user.clone();
        //给缓存中放一个clone体 重点
        userCache.put(username,clone);
        //返回它的克隆体
        return user;
    }


}
